﻿using AutoMapper;
using Gecko.Entities;
using Gecko.Models;
using Gecko.Models.Dto;
using Gecko.Respositories;
using Gecko.Util;
using log4net;
using NHibernate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Gecko.Services
{
    public class WaterLeakService : IDisposable
    {
        ILog _log = LogManager.GetLogger("Gecko.Services");
        private ISession _session;
        private WaterLeakRepository _waterLeakRepository;
        private WaterLeakResourceRepository _waterLeakResourceRepository;
        private UserInfoRepository _userInfoRepository;
        public WaterLeakService()
        {
            _session = NHibernateHelper.OpenSession();
            _waterLeakRepository = new WaterLeakRepository(_session);
            _userInfoRepository = new UserInfoRepository(_session);
            _waterLeakResourceRepository = new WaterLeakResourceRepository(_session);
        }

        public object GetWaterLeakHistory(int id)
        {
            var result = _waterLeakRepository.Get(id);
            if (result != null && result.Histories.Count > 0)
            {
                return result.Histories.OrderBy(p=>p.CreateDate).Select(p => new
                                                 {
                                                     State = p.State,
                                                     Date = p.CreateDate,
                                                     UserImg = p.UserInfo.Image,
                                                     UserId = p.UserInfo.Username,
                                                     UserName = p.UserInfo.Name
                                                 }).ToList();
            }else
            {
                throw new Exception("Not Found History");
            }
        }

        public List<ShortWaterLeakModel> GetShortWaterLeak(double lat, double lon)
        {
            var result = _waterLeakRepository.GetShortedWaterleak(lat, lon);
            List<ShortWaterLeakModel> shortedList = new List<ShortWaterLeakModel>();
            foreach (var shortWaterLeak in result)
            {
                ShortWaterLeakModel shortW = new ShortWaterLeakModel();
                shortW.Id = shortWaterLeak.Id;
                shortW.Detail = shortWaterLeak.Detail;
                shortW.Date = shortWaterLeak.CreateDate.ToString("dd/MM/yyyy hh:mm tt");
                shortW.Distance = (shortWaterLeak.Distance/1000d).ToString("0.00") + " km.";
                shortW.LatPoint = shortWaterLeak.LatPoint;
                shortW.LongPoint = shortWaterLeak.LongPoint;
                shortW.Topic = shortWaterLeak.Topic;
                shortW.User_id = shortWaterLeak.User_id;

                var resource =
                    _waterLeakResourceRepository.Get(p => p.WaterLeak.Id == shortWaterLeak.Id, null).FirstOrDefault();
                if (resource!=null)
                {
                    shortW.Image = resource.Id.ToString();
                }
                shortedList.Add(shortW);
            }
            return shortedList;
        }

        public ServiceResponse<IList<WaterLeakDto>> GetAllWaterLeak()
        {
            var response = new ServiceResponse<IList<WaterLeakDto>>();
            try
            {
                IList<WaterLeakWithFirstResourceUrl> waterLeakWithResource = _waterLeakRepository.GetAllWithResource();
                response.Data = Mapper.Map<IList<WaterLeakDto>>(waterLeakWithResource);
                response.Message = "Success";
                response.Page = 1;
                response.PageSize = 100;
                response.Status = true;
                response.Total = waterLeakWithResource.Count;
            }
            catch (Exception ex)
            {

                response.Status = false;
                response.Message = ex.Message;
                _log.Error(ex.Message, ex);
            }
            return response;
        }

        public void Dispose()
        {
            _session.Close();
        }

        public ServiceResponse<WaterLeakFullResDto> GetById(int id)
        {
            var response = new ServiceResponse<WaterLeakFullResDto>();
            try
            {
                response.Data = Mapper.Map<WaterLeakFullResDto>(_waterLeakRepository.GetByIdWithResource(id));
                response.Message = "success";
                response.Status = true;
            }
            catch (Exception ex)
            {
                response.Status = false;
                response.Message = ex.Message;
                _log.Error(ex.Message, ex);
            }
            return response;
        }

        public ServiceResponse<WaterLeakDto> AddWaterLeak(WaterLeakDto waterLeakDto)
        {
            var response = new ServiceResponse<WaterLeakDto>();
            var tx = _session.BeginTransaction();
            try
            {
                var userInfo = _userInfoRepository.Get(Convert.ToInt32(waterLeakDto.UserId));
                if (userInfo != null)
                {
                    var waterLeak = Mapper.Map<WaterLeak>(waterLeakDto);
                    waterLeak.User = userInfo;
                    waterLeak.CreateDate = DateTime.Now;
                    waterLeak.Histories = new List<WaterLeakHistory>();
                    WaterLeakHistory history = new WaterLeakHistory
                                      {
                                          CreateDate = DateTime.Now,
                                          Detail = String.Empty,
                                          State = "Open",
                                          UserInfo = userInfo
                                      };
                    _waterLeakRepository.Session.Save(history);
                    waterLeak.Histories.Add(history);
                    _waterLeakRepository.Add(waterLeak);
                    tx.Commit();
                    response.Data = Mapper.Map<WaterLeakDto>(waterLeak);
                    response.Message = "success";
                    response.Status = true;
                }
                else
                {
                    throw new Exception("Not Found User Info");
                }
            }
            catch (Exception ex)
            {
                if (tx.IsActive)
                {
                    tx.Rollback();
                }
                response.Status = false;
                response.Message = ex.Message;
                _log.Error(ex.Message, ex);
            }
            return response;
        }
    }
}